package cn.com.connext.scrm.service;

import cn.com.connext.scrm.config.Constants;
import cn.com.connext.scrm.domain.master.*;
import cn.com.connext.scrm.repository.master.*;
import cn.com.connext.scrm.service.dto.*;
import cn.com.connext.scrm.service.mapper.PrizeMapper;
import cn.com.connext.scrm.service.mapper.TaskService;
import cn.com.connext.scrm.utils.EntityUtils;
import cn.com.connext.scrm.utils.RedisUtils;
import cn.com.connext.scrm.web.rest.enums.AddPointEnum;
import cn.com.connext.scrm.web.rest.enums.PointSourceEnum;
import cn.com.connext.scrm.web.rest.enums.ReducePointEnum;
import cn.com.connext.scrm.web.rest.errors.MyErrorCode;
import cn.com.connext.scrm.web.rest.req.PointQueryReq;
import cn.com.connext.scrm.web.rest.req.TaskCreateReq;
import cn.com.connext.scrm.web.rest.req.TaskPointReq;
import cn.com.connext.scrm.web.rest.req.TaskQueryReq;
import cn.com.connext.scrm.web.rest.resp.PointQueryResp;
import cn.com.connext.scrm.web.rest.resp.QueryExperienceResp;
import cn.com.connext.scrm.web.rest.vm.QueryIdVM;
import cn.com.connext.scrm.web.rest.vm.QuestionnaireVM;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.connext.common.exception.ServiceException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.persistence.criteria.Predicate;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;
@Transactional
@Service
public class TaskServiceImpl implements TaskService {

    private final static String[] couponArr = {"9333557", "9557455"};
    private final Logger log = LoggerFactory.getLogger(TaskServiceImpl.class);
    @Autowired
    private TaskRepository taskRepository;
    private RestTemplate restTemplate = new RestTemplate();
    @Autowired
    private AccessTokenImpl accessTokenImpl;
    @Autowired
    private TaskRecordRepository taskRecordRepository;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private CouponRepository couponRepository;
    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private ZnhjRepository znhjRepository;
    @Autowired
    private PrizeRepository prizeRepository;
    @Autowired
    private PrizeGoodService prizeGoodService;

    @Autowired
    private PrizeMapper prizeMapper;

    @Autowired
    private ZnhjSkuPointRelationRepository znhjSkuPointRelationRepository;

    @Autowired
    private MemberRepository memberRepository;

    @Override
    public JsonResult create(TaskCreateReq req) {
        Task task = new Task();
        BeanUtils.copyProperties(req, task);
        if (null != req.getType()) {
            task.setId(String.valueOf(req.getType()));
        }
        task.setEnableFlag(false);
        task.setCreateTime(new Date());
        task.setUpdateTime(new Date());
        task = taskRepository.saveAndFlush(task);
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(0);
        jsonResult.setData(task);
        return jsonResult;
    }

    @Override
    public JsonResult update(TaskCreateReq req) {
        Task task = taskRepository.findOne(req.getId());
        BeanUtils.copyProperties(req, task);
        task.setEnableFlag(false);
        task.setUpdateTime(new Date());
        task = taskRepository.saveAndFlush(task);
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(0);
        jsonResult.setData(task);
        return jsonResult;
    }

//    @Override
//    public JsonResult audit(TaskAuditReq req) {
//        JsonResult jsonResult = new JsonResult();
//        Task task = taskRepository.findOne(req.getId());
//        if (null == task) {
//            jsonResult.setState(1);
//            jsonResult.setMessage("参数异常");
//            return jsonResult;
//        }
//        //保存问答表
//        task.setAuditResult(req.getAuditResult());//0初始状态  1审核通过  2 审核未通过
//        task.setEnableFlag(false);
//        task = taskRepository.saveAndFlush(task);
//        jsonResult.setState(0);
//        jsonResult.setData(task);
//        return jsonResult;
//    }

    @Override
    public JsonResult enable(QueryIdVM req) {
        JsonResult result = new JsonResult();
        Task task = taskRepository.findOne(req.getId());
        if (task == null) {
            throw new ServiceException(MyErrorCode.ERROR_DATA_ISNULL);
        }
        task.setEnableFlag(task.isEnableFlag() ? false : true);
        taskRepository.saveAndFlush(task);
        result.setMessage("操作成功");
        result.setState(0);
        return result;
    }

    @Override
    public JsonResult detail(String req) {
        JsonResult result = new JsonResult();
        Task task = taskRepository.findOne(req);
        if (task == null) {
            throw new ServiceException(MyErrorCode.ERROR_DATA_ISNULL);
        }
        TaskDTO taskDTO = new TaskDTO();
        BeanUtils.copyProperties(task, taskDTO);
        result.setState(0);
        result.setData(taskDTO);
        return result;
    }

    @Override
    public JsonResult pages(TaskQueryReq req) {
        int currentPage = (req.getCurrentPage() - 1) < 0 ? 0 : req.getCurrentPage() - 1;
        int pageSize = req.getPageSize() < 1 ? 10 : req.getPageSize();
        Pageable pageable = new PageRequest(currentPage, pageSize, new Sort(Sort.Direction.ASC, "reorder"));
        Specification<Task> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("enableFlag"), 1));
            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };
        Page<Task> page = taskRepository.findAll(specification, pageable);
        List<Task> taskList = page.getContent();
        List<TaskDTO> taskDTOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(taskList)) {
            taskDTOList = EntityUtils.dtoList2PojoList(taskList, TaskDTO.class);
        }
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndCreateTime(req.getUserId());
        taskDTOList.forEach(c -> {
            List<TaskRecord> taskRecordList = taskRecords.stream().filter(e -> e.getTaskType().compareTo(c.getType()) == 0).collect(Collectors.toList());
            if (c.getType().compareTo(5) == 0) {
                List<TaskRecord> taskRecordHeads = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), c.getType());
                c.setCompleteCount(taskRecordHeads.size());
            } else if (c.getType().compareTo(3) == 0) {
                List<TaskRecord> taskRecordNotes = taskRecordRepository.findByUserIdAndTaskTypeAnAndMonth(req.getUserId(), c.getType());
                c.setCompleteCount(taskRecordNotes.size());
            } else if (c.getType().compareTo(6) == 0) {
                c.setCompleteCount(CollectionUtils.isEmpty(taskRecordList) ? 0 : taskRecordList.size());
            } else if (c.getType().compareTo(8) == 0 || c.getType().compareTo(9) == 0) {
                List<TaskRecord> taskRecordNotes = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), c.getType());
                c.setCompleteCount(CollectionUtils.isNotEmpty(taskRecordNotes) ? 1 : 0);
            }else if (c.getType().compareTo(10) == 0) {
                //新增问卷状态
                List<TaskRecord> recordlist = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), 10);
                c.setCompleteCount(CollectionUtils.isNotEmpty(recordlist) ? 1 : 0);
            }else if (c.getType().compareTo(11) == 0) {
                //新增抽奖完成状态
                List<TaskRecord> recordlist = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), 11);
                c.setCompleteCount(CollectionUtils.isNotEmpty(recordlist) ? 1 : 0);
            }else if (c.getType().compareTo(12) == 0) {
                //新增兑换礼品完成状态
                List<TaskRecord> recordlist = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), 12);
                c.setCompleteCount(CollectionUtils.isNotEmpty(recordlist) ? 1 : 0);
            } else {
                List<TaskRecord> taskRecord = taskRecordRepository.findByUserIdAndTaskTypeAnAndMonth(req.getUserId(), c.getType());
                c.setCompleteCountMonth(taskRecord.size());
                c.setCompleteCount(CollectionUtils.isEmpty(taskRecordList) ? 0 : taskRecordList.size());
            }
        });
        PageImpl<TaskDTO> pageTasks = new PageImpl<>(taskDTOList, pageable, page.getTotalElements());
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(0);
        jsonResult.setData(pageTasks);
        return jsonResult;
    }

    @Override
    public JsonResult pageList(TaskQueryReq req) {
        int currentPage = (req.getCurrentPage() - 1) < 0 ? 0 : req.getCurrentPage() - 1;
        int pageSize = req.getPageSize() < 1 ? 10 : req.getPageSize();
        Pageable pageable = new PageRequest(currentPage, pageSize, new Sort(Sort.Direction.DESC, "createTime"));
        Specification<Task> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotEmpty(req.getContent())) {
                list.add(criteriaBuilder.like(root.get("content"), "%" + req.getContent() + "%"));
            }
            if (StringUtils.isNotEmpty(req.getTaskName())) {
                list.add(criteriaBuilder.like(root.get("taskName"), "%" + req.getTaskName() + "%"));
            }
            if (StringUtils.isNotEmpty(req.getDescription())) {
                list.add(criteriaBuilder.like(root.get("description"), "%" + req.getDescription() + "%"));
            }
            if (null != req.getEnableFlag()) {
                list.add(criteriaBuilder.equal(root.get("enableFlag"), req.getEnableFlag()));
            }
            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };
        Page<Task> page = taskRepository.findAll(specification, pageable);
        List<Task> taskList = page.getContent();
        List<TaskDTO> taskDTOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(taskList)) {
            taskDTOList = EntityUtils.dtoList2PojoList(taskList, TaskDTO.class);
        }
        PageImpl<TaskDTO> pageTasks = new PageImpl<>(taskDTOList, pageable, page.getTotalElements());
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(0);
        jsonResult.setData(pageTasks);
        return jsonResult;
    }

    @Override
    public JsonResult daily(TaskPointReq req) {
        JsonResult jsonResult = new JsonResult();
        //查询每日任务是否完成
        Task task = taskRepository.findOne(req.getId());
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskTypeAnAndCreateTime(req.getUserId(), task.getType());
        if (taskRecords.size() >= 1) {
            jsonResult.setState(1);
            jsonResult.setMessage("任务已完成，无法重复参加");
            return jsonResult;
        }
        // 增加：2021-12-20 添加原因：每日签到当MembershipId 相同，不同的UnionId 直接查询真实的字段
        //根据membershipId 查询member表 获取会员用户
        Member member = memberRepository.getMembershipId(req.getMembershipId());
        if (null == member){
            log.info("没有获取到会员信息 req: {}",JSON.toJSONString(req));
            jsonResult.setState(1);
            jsonResult.setMessage("没有获取到会员信息");
            return jsonResult;
        }
        // 用会员用户的union_id + task.getType() 这两个字段查询
        if ((member.getUnionId()).equals(req.getUserId())){
            StringBuilder  sb =new StringBuilder("daily");
            sb.append(req.getUserId()).append("-").append(req.getMembershipId()).append("-").append(task.getId());
            String flagKey = sb.toString();
            boolean flag = redisUtils.setIfAbsent(flagKey, flagKey);
            if(flag){
                jsonResult =rewriteCover(req,flagKey);
            }else{
                jsonResult.setState(1);
                jsonResult.setMessage("系统异常，请重试");
            }
        }
        return jsonResult;
    }

    @Override
    public JsonResult notes(TaskPointReq req) {
        JsonResult jsonResult = new JsonResult();
        //判断是否一日三次  审核通过 userId
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskTypeAnAndCreateTime(req.getUserId(), 2);
        if (taskRecords.size() >= 3) {
            jsonResult.setState(1);
            jsonResult.setMessage("每日发帖超过三次，无法获取积分");
            return jsonResult;
        }
        //判断师傅一月20次
        List<TaskRecord> taskRecordList = taskRecordRepository.findByUserIdAndTaskTypeAnAndMonth(req.getUserId(), 2);
        if (taskRecordList.size() >= 20) {
            jsonResult.setState(1);
            jsonResult.setMessage("每月发帖超过20次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        return jsonResult;
    }

    @Override
    public JsonResult comment(TaskPointReq req) {
        //成功发表，每日上限记3次，每月上限记20次
        JsonResult jsonResult = new JsonResult();
        //判断是否一日三次  审核通过 userId
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskTypeAnAndCreateTime(req.getUserId(), 4);
        if (taskRecords.size() >= 3) {
            jsonResult.setState(1);
            jsonResult.setMessage("每日评论超过三次，无法获取积分");
            return jsonResult;
        }
        //判断师傅一月20次
        List<TaskRecord> taskRecordList = taskRecordRepository.findByUserIdAndTaskTypeAnAndMonth(req.getUserId(), 4);
        if (taskRecordList.size() >= 20) {
            jsonResult.setState(1);
            jsonResult.setMessage("每月评论超过20次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        return jsonResult;
    }

    @Override
    public JsonResult browseRecord(TaskPointReq req) {
        JsonResult jsonResult = new JsonResult();
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskTypeAnAndCreateTime(req.getUserId(), 6);
        //识别有效阅读行为，每日上限记5次
        if (taskRecords.size() >= 5) {
            jsonResult.setState(1);
            jsonResult.setMessage("效阅读行为，超过5次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        return jsonResult;
    }

    @Override
    public JsonResult updateImage(TaskPointReq req) {
        //修改头像2次  任务type=1
        JsonResult jsonResult = new JsonResult();
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), 5);
        if (taskRecords.size() >= 2) {
            jsonResult.setState(1);
            jsonResult.setMessage("修改头像超过2次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        return jsonResult;
    }

    @Override
    public JsonResult repeat(TaskPointReq req) {
        //成功转发，每日上限记3次，每月上限记20次
        JsonResult jsonResult = new JsonResult();
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskTypeAnAndCreateTime(req.getUserId(), 7);
        if (taskRecords.size() >= 3) {
            jsonResult.setState(1);
            jsonResult.setMessage("每日转发超过3次，无法获取积分");
            return jsonResult;
        }
        List<TaskRecord> taskRecordList = taskRecordRepository.findByUserIdAndTaskTypeAnAndMonth(req.getUserId(), 7);
        if (taskRecordList.size() >= 20) {
            jsonResult.setState(1);
            jsonResult.setMessage("每月转发超过20次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        return jsonResult;
    }

    @Override
    public JsonResult essences(TaskPointReq req) {
        JsonResult jsonResult = new JsonResult();
        //获取memberShipId
        String accessToken = accessTokenImpl.getAccessToken();
        //调用外部系统接口
        String requestUrl = Constants.GetMembershipByIdentityUrl.replace("ACCESS_TOKEN", accessToken).replace("TYPE", "wechat-unionid").replace("VALUE", req.getUserId());
        ResponseEntity<JSONObject> obj = restTemplate.getForEntity(requestUrl, JSONObject.class);
        if (!obj.getBody().containsKey("error")) {
            //更新MembershipId
            req.setMembershipId(obj.getBody().getJSONObject("membership").getString("id"));
        } else {
            log.info("精华帖，获取memberShipId异常。userId={}", req.getUserId());
            jsonResult.setState(1);
            jsonResult.setMessage("服务异常请重试");
            return jsonResult;
        }
        List<TaskRecord> taskRecordList = taskRecordRepository.findByUserIdAndTaskTypeAnAndMonth(req.getUserId(), 3);
        if (taskRecordList.size() >= 1) {
            jsonResult.setState(1);
            jsonResult.setMessage("精华帖每月一次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        return jsonResult;
    }

    @Override
    public JsonResult membership(TaskPointReq req) {
        log.info("注册会员成功添加积分：任务id->{}",req.getId());
        JsonResult jsonResult = new JsonResult();
        Task task = taskRepository.findOne(req.getId());
        List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskType(req.getUserId(), task.getType());
        if (taskRecords.size() >= 1) {
            log.info("非法操作 req: {}",JSON.toJSONString(req));
            jsonResult.setState(1);
            jsonResult.setMessage(task.getType().compareTo(8) == 0 ? "入会礼超过一次，无法获取积分" : "完善个人信息超过一次，无法获取积分");
            return jsonResult;
        }
        //根据membershipId 查询member表 获取会员用户
        Member member = memberRepository.getMembershipId(req.getMembershipId());
        if (null == member){
            log.info("没有获取到会员信息 req: {}",JSON.toJSONString(req));
            jsonResult.setState(1);
            jsonResult.setMessage("没有获取到会员信息");
            return jsonResult;
        }
        // 用会员用户的union_id + task.getType() 这两个字段查询
        List<TaskRecord> taskRecordList = taskRecordRepository.findByUserIdAndTaskType(member.getUnionId(), task.getType());
        //验证返回数据大于等于1  提示 401行的提示信息;
        if (taskRecordList.size() >= 1) {
            log.info("非法操作 req: {}",JSON.toJSONString(req));
            jsonResult.setState(1);
            jsonResult.setMessage(task.getType().compareTo(8) == 0 ? "入会礼超过一次，无法获取积分" : "完善个人信息超过一次，无法获取积分");
            return jsonResult;
        }
        jsonResult = cover(req);
        //入会发放2张优惠卷满99-10 满399-50
        List<OrderRecord> orders = new ArrayList<>();
        if (task.getType().compareTo(8) == 0) {
            Arrays.stream(couponArr).forEach(c -> {
                OrderRecord order = new OrderRecord();
                order.setCount(1);
                order.setOrderCode(getOrderCode());
                order.setState(1);
                order.setType(1);
                order.setMembershipId(req.getMembershipId());
                order.setCouponId(c);
                order.setUserId(req.getUserId());
                order.setOrderTime(new Date());
                order.setCreateTime(new Date());
                order.setUpdateTime(new Date());
                order = orderRepository.saveAndFlush(order);
                orders.add(order);
            });
        }
        if (orders.size() != 2) {
            //入会有赞卷数量不足，联系管理员
            jsonResult.setState(1);
            jsonResult.setMessage("入会有赞卷数量不足，联系管理员");
        }
        return jsonResult;
    }

    @Override
    public JsonResult pointList(PointQueryReq req) {
        log.info("【pointList】->{},{},{}",req.getCurrentPage(),req.getMembershipId(),req.getType());
        JsonResult jsonResult = new JsonResult();
        String accessToken = accessTokenImpl.getAccessToken();
        //获取最新积分
        log.info("积分查询入参:MEMBERSHIP->{},PAGE->{},ACCESSTOKEN->{}", req.getMembershipId(), req.getCurrentPage(), accessToken);
        String requestUrlNew = Constants.PointList.replace("MEMBERSHIP", req.getMembershipId()).replace("ROWS", "10").replace("PAGE", "1").replace("ACCESSTOKEN", accessToken);
        log.info("请求入参：requestUrlNew->{}",requestUrlNew);
        JSONObject resultNew = restTemplate.getForEntity(requestUrlNew, JSONObject.class).getBody();
        log.info("请求出参：resultNew->{}",resultNew);

        String errorNew = resultNew.getString("error_description");
        if (StringUtils.isNotBlank(errorNew)) {
            jsonResult.setState(1);
            jsonResult.setMessage("积分查询异常，请重新尝试");
            return jsonResult;
        }
        PointQueryResp pointQueryRespNew = JSONObject.parseObject(JSON.toJSONString(resultNew), PointQueryResp.class);
        String requestUrl = Constants.PointList.replace("MEMBERSHIP", req.getMembershipId()).replace("ROWS", req.getPageSize()).replace("PAGE", req.getCurrentPage()).replace("ACCESSTOKEN", accessToken);
        log.info("请求入参：requestUrl->{}",requestUrl);
        JSONObject result = restTemplate.getForEntity(requestUrl, JSONObject.class).getBody();
        log.info("请求出参：result->{}",result);
        String error = result.getString("error_description");
        if (StringUtils.isNotBlank(error)) {
            jsonResult.setState(1);
            jsonResult.setMessage("积分查询异常，请重新尝试");
            return jsonResult;
        }
        PointQueryResp pointQueryResp = JSONObject.parseObject(JSON.toJSONString(result), PointQueryResp.class);
        if (CollectionUtils.isNotEmpty(pointQueryResp.getRows())) {
            pointQueryResp.setNewPoint(pointQueryResp.getRows().get(0).getNewPoint());
        }
        jsonResult.setData(pointQueryResp);
        Integer total = pointQueryResp.getRecords();
        String requestUrlAll = Constants.PointList.replace("MEMBERSHIP", req.getMembershipId()).replace("ROWS", total.toString()).replace("PAGE", req.getCurrentPage()).replace("ACCESSTOKEN", accessToken);
        log.info("请求入参：requestUrlAll->{}",requestUrlAll);
        JSONObject resultAll = restTemplate.getForEntity(requestUrlAll, JSONObject.class).getBody();
        log.info("请求入参：resultAll->{}",resultAll);

        Object errorAll = resultAll.getJSONObject("error");
        if (null != errorAll) {
            jsonResult.setState(1);
            jsonResult.setMessage("积分查询异常，请重新尝试");
            return jsonResult;
        }
        PointQueryResp pointQueryRespAll = JSONObject.parseObject(JSON.toJSONString(resultAll), PointQueryResp.class);
        if (CollectionUtils.isNotEmpty(pointQueryRespNew.getRows())) {
            pointQueryResp.setNewPoint(pointQueryRespNew.getRows().get(0).getNewPoint());
        }
        //获取当天积分之和
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'");
        String timeStamp = formatter.format(new Date());
        int pointsNow = pointQueryRespAll.getRows().stream().filter(c -> c.getLastUpdated().contains(timeStamp)).mapToInt(PointListDTO::getPoint).sum();
        pointQueryResp.setPointTotlesNow(pointsNow);
        //全部
        if (req.getType().compareTo(0) == 0) {
            List<PointListDTO> pointListDTOS = pointQueryResp.getRows();
            pointListDTOS = coverPointListDTOList(pointListDTOS);
            pointQueryResp.setRows(pointListDTOS);
            jsonResult.setData(pointQueryResp);
            return jsonResult;
        }
        //增加
        if (req.getType().compareTo(1) == 0) {
            List<PointListDTO> pointListDTOS = pointQueryRespAll.getRows();
            List<PointListDTO> pointListDTOList = coverPointListDTOList(pointListDTOS.stream().filter(c -> c.getType().compareTo(1) == 0).collect(Collectors.toList()));
            pointQueryResp.setRows(pointListDTOList);
            pointQueryResp.setRecords(CollectionUtils.isNotEmpty(pointListDTOS) ? pointListDTOS.stream().filter(c -> c.getType().compareTo(1) == 0).collect(Collectors.toList()).size() : new Integer(0));
            pointQueryResp.setTotal(1);
            jsonResult.setData(pointQueryResp);
            return jsonResult;
        }
        //减积分
        List<PointListDTO> pointListDTOS = pointQueryRespAll.getRows();
        List<PointListDTO> pointListDTOList = coverPointListDTOList(pointListDTOS.stream().filter(c -> c.getType().compareTo(-1) == 0).collect(Collectors.toList()));
        pointQueryResp.setRows(pointListDTOList);
        pointQueryResp.setTotal(1);
        jsonResult.setData(pointQueryResp);
        return jsonResult;
    }

    private List<PointListDTO> coverPointListDTOList(List<PointListDTO> req) {
        if (CollectionUtils.isNotEmpty(req)) {
            req.forEach(c -> {
                c.setSourceType(PointSourceEnum.getValue(c.getSource()));
                if (c.getType().compareTo(1) == 0) {
                    c.setContentName(StringUtils.isEmpty(c.getContentName()) ? AddPointEnum.getValue(c.getPattern()) : c.getContentName());
                }
                if (c.getType().compareTo(-1) == 0) {
                    if (c.getPattern().compareTo(1) == 0 && c.getSource().equals("帝亚吉欧会员俱乐部")) {
                        c.setImageUrl(StringUtils.isNotEmpty(c.getRemark()) ? c.getRemark() : null);
                    }
                    c.setContentName(StringUtils.isEmpty(c.getContentName()) ? ReducePointEnum.getValue(c.getPattern()) : c.getContentName());
                }

            });
            return req;
        }
        return Collections.emptyList();
    }

    private JsonResult cover(TaskPointReq req) {
        JsonResult jsonResult = new JsonResult();
        //查询任务配置
        Task task = taskRepository.findOne(req.getId());
        String accessToken = accessTokenImpl.getAccessToken();
        String requestUrl = Constants.PointIncr.replace("MEMBERSHIP", req.getMembershipId()).replace("ACCESSTOKEN", accessToken);
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        Date currentTime = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentTime);
        calendar.add(Calendar.HOUR, -8);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        String timeStamp = formatter.format(calendar.getTime());
        //调用微信请求实体
        PointDTO pointDTO = new PointDTO();
        pointDTO.setPoint(task.getPoint());
        pointDTO.setContentName(task.getTaskName());
        pointDTO.setDate(timeStamp);
        pointDTO.setPattern(3);//互动积分传值"3"，
        if (task.getType().compareTo(7) == 0) {
            pointDTO.setRemark(req.getContent());
        }
        pointDTO.setSource("帝亚吉欧会员俱乐部");
        HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(pointDTO), headers);
        JSONObject result = restTemplate.postForObject(requestUrl, httpEntity, JSONObject.class);
        log.info("每日任务调用返回信息: {}", result.toString());
        Object error1 = result.getJSONObject("error");
        if (null != error1) {
            log.info("每日任务调用crm接口返回error!");
            CrmErrorDTO crmErrorDTO = JSON.parseObject(JSON.toJSONString(error1), CrmErrorDTO.class);
            log.info("每日任务调用异常返回信息: {}", crmErrorDTO.toString());
            jsonResult.setState(1);
            jsonResult.setData(crmErrorDTO);
            jsonResult.setMessage("每日任务异常，请重新尝试");
            return jsonResult;
        }
        PointDTO pointDto = JSON.parseObject(JSON.toJSONString(result), PointDTO.class);
        TaskRecord taskRecord = new TaskRecord();
        taskRecord.setCreateTime(new Date());
        taskRecord.setTaskType(task.getType());
        taskRecord.setUserId(req.getUserId());
        taskRecordRepository.saveAndFlush(taskRecord);
        jsonResult.setState(0);
        jsonResult.setData(pointDto);
        return jsonResult;
    }

    private JsonResult rewriteCover(TaskPointReq req,String flagKey) {
        JsonResult jsonResult = new JsonResult();
        //查询任务配置
      try {
          Task task = taskRepository.findOne(req.getId());
          String accessToken = accessTokenImpl.getAccessToken();
          String requestUrl = Constants.PointIncr.replace("MEMBERSHIP", req.getMembershipId()).replace("ACCESSTOKEN", accessToken);
          HttpHeaders headers = new HttpHeaders();
          MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
          headers.setContentType(type);
          Date currentTime = new Date();
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(currentTime);
          calendar.add(Calendar.HOUR, -8);
          SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
          String timeStamp = formatter.format(calendar.getTime());
          //调用微信请求实体
          PointDTO pointDTO = new PointDTO();
          pointDTO.setPoint(task.getPoint());
          pointDTO.setContentName(task.getTaskName());
          pointDTO.setDate(timeStamp);
          pointDTO.setPattern(3);//互动积分传值"3"，
          if (task.getType().compareTo(7) == 0) {
              pointDTO.setRemark(req.getContent());
          }
          pointDTO.setSource("帝亚吉欧会员俱乐部");
          HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(pointDTO), headers);
          JSONObject result = restTemplate.postForObject(requestUrl, httpEntity, JSONObject.class);
          log.info("每日任务调用返回信息: {}", result.toString());
          Object error1 = result.getJSONObject("error");
          if (null != error1) {
              log.info("每日任务调用crm接口返回error!");
              CrmErrorDTO crmErrorDTO = JSON.parseObject(JSON.toJSONString(error1), CrmErrorDTO.class);
              log.info("每日任务调用异常返回信息: {}", crmErrorDTO.toString());
              jsonResult.setState(1);
              jsonResult.setData(crmErrorDTO);
              jsonResult.setMessage("每日任务异常，请重新尝试");
              return jsonResult;
          }
          PointDTO pointDto = JSON.parseObject(JSON.toJSONString(result), PointDTO.class);
          TaskRecord taskRecord = new TaskRecord();
          taskRecord.setCreateTime(new Date());
          taskRecord.setTaskType(task.getType());
          taskRecord.setUserId(req.getUserId());
          taskRecordRepository.saveAndFlush(taskRecord);
          jsonResult.setState(0);
          jsonResult.setData(pointDto);
      }catch (Exception e){
          jsonResult.setState(1);
          jsonResult.setMessage("每日任务异常，请重新尝试");
      }finally {
          redisUtils.remove(flagKey);
      }
      return jsonResult;
    }

    @Override
    public JsonResult queryExperience() {
        JsonResult jsonResult = new JsonResult();
        //获取token
        try {
            String accessToken = accessTokenImpl.getAccessToken();
            //调用外部系统接口
            String requestUrl = Constants.QueryExperienceUrl.replace("ACCESS_TOKEN", accessToken);
            String obj = restTemplate.getForEntity(requestUrl, String.class).getBody();
            log.info("obj={}", obj);
            List<QueryExperienceResp> result = JSON.parseArray(obj, QueryExperienceResp.class);
            jsonResult.setData(result);
            jsonResult.setState(0);
        } catch (RestClientException e) {
            jsonResult.setMessage("系统异常，请重试");
            jsonResult.setState(1);
            return jsonResult;
        }
        return jsonResult;
    }

    @Override
    @Transactional
    public JsonResult scanCode(ZnhjEntity sti) {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(0);
        ZnhjEntity znhj =znhjRepository.finByBottomCode(sti.getBottleCode());
        int point =0;
        ZnhjSkuPointRelation znhjSkuPointRelation =null;
        PrizeGood good =null;
        if(znhj !=null){
            znhjSkuPointRelation =znhjSkuPointRelationRepository.findBySkuId(znhj.getSkuId());
            if(znhjSkuPointRelation !=null && znhjSkuPointRelation.getPoint() !=null){
                good = prizeGoodService.findCanUse(znhjSkuPointRelation.getGoodId());
                if(good !=null){
                    if(good.getStock()==0){
                        jsonResult.setState(-1);
                        jsonResult.setMessage("库存不足");
                        return jsonResult;
                    }else{
                        jsonResult.setMessage("恭喜您获得"+good.getPoint()+"积分！");
                    }
                }else{
                    jsonResult.setState(-1);
                    jsonResult.setMessage("奖品暂未开启");
                    return jsonResult;
                }
            }
            Prize prize = new Prize();
            prize.setUnionId(sti.getUnionId());
            //奖品ID
            prize.setGoodId(znhjSkuPointRelation.getGoodId());
            prize.setCreateTime(new Date());
            prize.setUpdateTime(new Date());
            prize.setAddPoint(false);
            if (StringUtils.isNotEmpty(znhjSkuPointRelation.getActivityId())) {
                prize.setActivityId(znhjSkuPointRelation.getActivityId());
            }
            point=good.getPoint();
            prizeRepository.saveAndFlush(prize);
            //通过奖品ID获取当前时间的奖品
//            PrizeGood good = prizeGoodService.findById(znhjSkuPointRelation.getGoodId());
            PrizeDTO dto = prizeMapper.toDto(prize);
            dto.setGoodName(good.getGoodName());
            dto.setType(good.getType());
            //增加奖品图片
            if (StringUtils.isNotEmpty(good.getGoodImg())) {
                dto.setGoodImg(good.getGoodImg());
            }
            if (StringUtils.isNotEmpty(good.getGoodImg())) {
                dto.setPagePath(good.getPagePath());
            }
            if (null != good.getPoint()) {
                dto.setPoint(good.getPoint());
            }
            if (StringUtils.isNotEmpty(good.getCardId())) {
                dto.setCardId(good.getCardId());
            }
            if (StringUtils.isNotEmpty(good.getCode())) {
                dto.setCode(good.getCode());
            }
            log.info("dto:{}", dto.toString());
            if (good.getType() == 0) {
                if (good.getPoint() == null || good.getPoint() == 0) {
                    good.setPoint(50);
                }
            }
//            final Integer prizeId = prize.getId();
//            if (good.getType() == 0) {
//                ExecutorService service = Executors.newSingleThreadExecutor();
//                service.execute(() -> {
//                    addPoint(sti, good.getPoint(), prizeId);
//                    log.info("加分结束");
//                });
//            }

            dto.setButtonText(good.getButtonText());

            if (good.getRemark()!=null){
                dto.setRemark(good.getRemark());
            }

            if (good.getPathType()!=null){
                dto.setPathType(good.getPathType());
            }
            if (good.getAppId()!=null){
                dto.setAppId(good.getAppId());
            }
            jsonResult.setData(dto);
            log.info("membershipId:{}",sti.getMembershipId());
            log.info("point:{}",point);
            log.info("prizeId:{}",prize.getId());
            addPoint(sti.getMembershipId(),point,prize.getId(),sti.getUnionId());
            Boolean flag = cutStock(znhjSkuPointRelation.getGoodId(), znhjSkuPointRelation.getActivityId());
            if (!flag) {
                jsonResult.setState(-1);
                jsonResult.setMessage("系统繁忙");
                return jsonResult;
            }
        }
        ZnhjEntity entity = znhjRepository.findByUniqueCodeAndBottomCode(sti.getUniqueCode(), sti.getBottleCode());
        if(entity !=null){
            entity.setActivityTime(ZonedDateTime.now());
            entity.setIsActivity(1);
            entity.setUnionId(sti.getUnionId());
            entity.setMembershipId(sti.getMembershipId());
            entity.setPoint(point);
            znhjRepository.saveAndFlush(entity);
        }
        return jsonResult;
    }



    private String getOrderCode() {
        Random random = new Random();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String correntTime = simpleDateFormat.format(new Date());
        String result = "N" + correntTime + random.nextInt(10);
        return result;
    }

    private Boolean cutStock(Integer goodId, String activityId) {
        Boolean flag = prizeGoodService.cutStock(goodId, activityId);
        return flag;
    }
    private void addPoint(String memberShipId, Integer addPoint, Integer prizeId,String unionId) {
        String accessToken = accessTokenImpl.getAccessToken();
        log.info("accessToken:{}",accessToken);
        log.info("addPoint:{}",addPoint);
        log.info("prizeId:{}",prizeId);
        log.info("membershipId:{}",memberShipId);
        String requestUrl = Constants.PointIncr.replace("MEMBERSHIP", memberShipId).replace("ACCESSTOKEN", accessToken);
        PointDTO dto = new PointDTO();
        Date currentTime = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentTime);
        calendar.add(Calendar.HOUR, -8);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        String timeStamp = formatter.format(calendar.getTime());
        dto.setContentName("扫码获取积分");
        dto.setSource("尊尼获加黑牌俱乐部");
        dto.setDate(timeStamp);
        dto.setPattern(4);
        dto.setPoint(addPoint);
        OkHttpClient client = new OkHttpClient().newBuilder()
            .build();
        okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(dto));
        Request request = new Request.Builder()
            .url(requestUrl)
            .method("POST", body)
            .addHeader("Content-Type", "application/json")
            .build();
        try {
            Response response = client.newCall(request).execute();
            String result = new String(response.body().bytes());
            log.info("调用加分接口,返回值:{}", result);
            Prize prize = prizeRepository.findOne(prizeId);
            prize.setAddPoint(true);
            Prize prize1 = prizeRepository.saveAndFlush(prize);
            List<TaskRecord> list = taskRecordRepository.findByUserIdAndTaskType(unionId,11);
            if(list == null || list.size() ==0){
                TaskRecord taskRecord = new TaskRecord();
                taskRecord.setCreateTime(new Date());
                taskRecord.setTaskType(11);
                taskRecord.setUserId(unionId);
                taskRecordRepository.save(taskRecord);
                log.info("尊尼获加活动本地第一次抽奖添加积分完成");
                PointDTO dto2 = new PointDTO();
                dto2.setContentName("第一次抽奖赠送积分");
                dto2.setSource("帝亚吉欧会员俱乐部");
                dto2.setDate(timeStamp);
                dto2.setPattern(4);//第一次积分兑礼
                dto2.setPoint(10);
                RequestBody body2 = RequestBody.create(mediaType, JSON.toJSONString(dto2));
                Request request2 = new Request.Builder()
                    .url(requestUrl)
                    .method("POST", body2)
                    .addHeader("Content-Type", "application/json")
                    .build();
                try {
                    Response response2 = client.newCall(request2).execute();
                    String jsresult = new String(response2.body().bytes());
                    log.info("调用加分接口,返回值:{}", jsresult);
                    response.body().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            log.info("加分操作完,prize1:{}", prize1.getAddPoint());
            response.body().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public JsonResult queryQuestionnaireByUnionId(QuestionnaireVM vm) {
        JsonResult jsonResult =new JsonResult();
        if(vm ==null || StringUtils.isEmpty(vm.getUnionId())){
            jsonResult.setState(-1);
            jsonResult.setMessage("参数有误!");
        }else{
            List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskType(vm.getUnionId(), 10);
            if(taskRecords !=null && taskRecords.size() >0){
                jsonResult.setState(1);
                jsonResult.setMessage("已完成答卷");
            }else{
                jsonResult.setState(0);
                jsonResult.setMessage("未完成答卷");
            }
        }
        return jsonResult;
    }

    @Override
    public JsonResult questionnaireFinish(QuestionnaireVM vm) {
        JsonResult jsonResult =new JsonResult();
        if(vm ==null || StringUtils.isEmpty(vm.getUnionId())){
            jsonResult.setState(-1);
            jsonResult.setMessage("参数有误!");
        }else{
            List<TaskRecord> taskRecords = taskRecordRepository.findByUserIdAndTaskType(vm.getUnionId(), 10);
            if(taskRecords !=null && taskRecords.size() >0){
                jsonResult.setState(1);
                jsonResult.setMessage("该用户存在问卷记录，无法重复参加!");
            }else{
                TaskRecord taskRecord = new TaskRecord();
                taskRecord.setCreateTime(new Date());
                taskRecord.setTaskType(10);
                taskRecord.setUserId(vm.getUnionId());
                taskRecordRepository.saveAndFlush(taskRecord);
                jsonResult.setState(0);
                jsonResult.setMessage("操作成功");
            }
        }
        return jsonResult;
    }

}
